package org.example.netty.utils;

/**
 * @author:hzc
 * @date:2025/05/27
 * @desc:
 */
public class SnowflakeIdGenerator {
    private final static long START_TIMESTAMP = 1609459200000L; // 自定义起始时间
    private final static long MACHINE_ID_BITS = 10;
    private final static long SEQUENCE_BITS = 12;

    private final static long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);
    private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);

    private final static long MACHINE_ID_SHIFT = SEQUENCE_BITS;
    private final static long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;

    private final long machineId;

    private long lastTimestamp = -1L;
    private long sequence = 0L;

    public SnowflakeIdGenerator(long machineId) {
        if (machineId > MAX_MACHINE_ID) {
            throw new IllegalArgumentException("machineId 超过最大限制");
        }
        this.machineId = machineId;
    }

    public synchronized long nextId() {
        long currentTimestamp = System.currentTimeMillis();
        if (currentTimestamp < lastTimestamp) {
            throw new RuntimeException("系统时间回拨");
        }

        if (currentTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0) {
                // 当前毫秒内序列号用尽，等待下一毫秒
                while ((currentTimestamp = System.currentTimeMillis()) <= lastTimestamp) {
                    Thread.yield();
                }
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = currentTimestamp;

        return ((currentTimestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT)
                | (machineId << MACHINE_ID_SHIFT)
                | sequence;
    }
}

